package com.wynn.controller;

import com.wynn.pojo.ManHour;
import com.wynn.pojo.Result;
import com.wynn.serviceFeign.ProcedureClient;
import com.wynn.utils.FilesUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("procedure")
public class ProcedureController {

    @Autowired
    private ProcedureClient procedureClient;

    //查看流程程序图
    @GetMapping("/download")
    public void download(HttpServletResponse response, String model) throws Exception {
        ServletOutputStream out = null;
        ByteArrayOutputStream baos = null;

        try {
            String projectPath =   ResourceUtils.getURL("classpath:").getPath().split("target")[0];
            String filePath = projectPath+"\\src\\main\\resources\\procedure\\";
            //根据型号获取程序文件名，包括后缀
            String fileName = FilesUtils.findFileByName(filePath,model);
            if(fileName.equals("")){
                log.warn("查看程序图时，未选择产品");
                throw new Exception();
            }

            File file = new File(filePath+fileName);
            InputStream inStream=new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            baos =new ByteArrayOutputStream();
            while ((len = inStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            log.info("查看产品" +model+"生产流程程序图失败");
            response.addHeader("Content-Disposition", "attachment;filename=");
            response.addHeader("Content-Length", "" + baos.size());
            response.setHeader("filename", fileName);
            response.setContentType("application/octet-stream");
            out = response.getOutputStream();

            out.write(baos.toByteArray());

        } catch (Exception e) {
            log.warn("查看产品" +model+"生产流程程序图失败");
            e.printStackTrace();
            throw new RuntimeException();
        } finally {
            if (baos!=null){
                baos.flush();
                baos.close();
            }
            if(out!=null){
                out.flush();
                out.close();
            }

        }

    }

    @PostMapping("updateProcedure")
    @PreAuthorize("hasRole('process') || hasRole('admin')")
    public void updateProcedure(MultipartFile file, String productModel) throws Exception {

        //获取项目存放的路径
        String projectPath =   ResourceUtils.getURL("classpath:").getPath().split("target")[0];
        //获取文件的后缀
        String fileSuffix = file.getOriginalFilename().split("\\.")[1];
        //获取文件存在路径
        String filePath = projectPath+"\\src\\main\\resources\\procedure\\";
        //删除已存在文件
        FilesUtils.deleteByName(filePath,productModel);
        File src = new File(filePath+productModel+"."+fileSuffix);
        file.transferTo(src);
        log.info("查看产品" +productModel+"生产流程程序图");

    }

    @GetMapping("exportProcedure")
    @PreAuthorize("hasRole('process') || hasRole('admin')")
    public void exportProcedure(HttpServletResponse response,String model) throws Exception {

        //项目路径
        String projectPath =   ResourceUtils.getURL("classpath:").getPath().split("target")[0];
        //文件路径
        String filePath = projectPath+"\\src\\main\\resources\\procedure\\";
        //根据型号获取程序文件名，包括后缀
        String fileName = FilesUtils.findFileByName(filePath,model);

        // 读到流中
        InputStream inputStream = new FileInputStream(filePath+fileName);// 文件的存放路径
        response.reset();
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));

        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        outputStream.flush();
        outputStream.close();
        inputStream.close();
        log.info("查看产品" +model+"生产流程程序图");

    }

    @GetMapping("selectAll")
    public Result selectAll(){
        Result result = new Result();
        try{
            List<ManHour> man_hours = procedureClient.selectAll();
            result.setData(man_hours);
            result.setCode("200");
        }catch (Exception E){
            result.setCode("503");
            log.warn("加载工时失败");
            result.setMessage("工时加载失败");
        }
        return result;
    }

    @PostMapping("importHour")
    @PreAuthorize("hasRole('process') || hasRole('admin')")
    public void importHour(MultipartFile file) throws Exception {
        ArrayList<ArrayList<String>> hourTable = new ArrayList<>();
        InputStream in = null;
        try {
            //获取输入流
            in = file.getInputStream();
            Workbook workbook = new XSSFWorkbook(in);
            //获取第一张工作表
            Sheet sheet = workbook.getSheetAt(0);

            for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
                //循环获取每一列
                ArrayList<String> cell = new ArrayList<>();
                //循环获取表的每一行
                Row row = sheet.getRow(i);
                for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {   //
                    //将每一个单元格的值装入列集合
                    row.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
                    cell.add(row.getCell(j).getStringCellValue());
                }
                //将装有每一列的集合装入大集合
                hourTable.add(cell);
            }
            procedureClient.importHour(hourTable);
            log.info("导入工时");
        } catch (FileNotFoundException e) {
            log.warn("导入工时失败");
            e.printStackTrace();
            throw new Exception();
        } catch (IOException e) {
            log.warn("导入工时失败");
            e.printStackTrace();
            throw new Exception();
        }finally {
            //关闭资源
            if (in != null) {
                in.close();
            }
        }
    }

    @GetMapping("search")
    public Result search(String name){
        Result result = new Result();
        try{
            List<ManHour> manHours = procedureClient.search(name);
            result.setMessage("查询成功");
            result.setCode("200");
            result.setData(manHours);
        }catch (Exception e){
            log.warn("查询工时失败");
            result.setMessage("查询失败");
            result.setCode("503");
        }
        return result;
    }

    @GetMapping("findTT")
    public Result findTT(){
        Result result = new Result();
        try{
            float TT = procedureClient.findTT();
            result.setMessage("查询成功");
            result.setCode("200");
            result.setData(TT);
        }catch (Exception e){
            log.warn("查询节拍失败");
            result.setMessage("查询节拍失败");
            result.setCode("503");
        }
        return result;
    }

    @GetMapping("updateTT")
    @PreAuthorize("hasRole('process') || hasRole('admin')")
    public Result updateTT(float tt){
        Result result = new Result();
        try{
            procedureClient.updateTT(tt);
            result.setMessage("修改节拍成功");
            result.setCode("200");
        }catch (Exception e){
            log.warn("更新节拍失败");
            result.setMessage("修改节拍失败");
            result.setCode("503");
        }
        return result;
    }

}
